---
title: 'Social Authentication: Cypress Guide'
sidebar_label: Social Authentication
description: Authenticate with common social authentication platforms with cy.origin() and use cy.session() to cache authenticated users.
---

<ProductHeading product="app" />

# Social Authentication

:::info

##### <Icon name="question-circle" color="#4BBFD2" /> What you'll learn

- How to authenticate with Auth0 for Tenant with `cy.origin()`
- How to use `cy.session()` to cache authenticated users

:::

:::caution

<Icon name="exclamation-triangle" /> **Not recommended in CI**

Cypress does **not** recommend testing social connection authentication as a
primary means of authentication testing. This is due to the
[challenges](/app/core-concepts/best-practices#Potential-Challenges-Authenticating-with-Social-Platforms)
mentioned in our
[Best Practices Guide](/app/core-concepts/best-practices).

Relying on social authentication in CI will likely result in bot detection and
in some cases, account suspension due to violating the provider's Terms of
Service.

:::

## Application Setup

For this guide, we're going to set up an application that uses Auth0 for Tenant
that has social connections set up for Google, Facebook, and Microsoft which
will authenticate users on our behalf to our application.

### Set up the Auth0 tenant

To get started, first create a free [Auth0](https://auth0.com/signup)
account and select the **I am a new Auth0 User** flow. This will have 4 steps:

- **Step 1:** When configuring your Sample App, please select the
  **Single-Page App** for you platform and **React** for the technology.
- **Step 2:** For **Social Connections**, please select **Facebook**, **Microsoft**, and
  **Google**
- **Step 3:** Try login and verify the connections are set up properly
- **Step 4:** You can either download the sample via the **Download Sample App**
  button or clone it
  [here](https://github.com/auth0-samples/auth0-react-samples/tree/d5848ed710db85d6ef060731b296603c0eca744b/Sample-01).
  We'll need this application in the next step. Select
  **I am Ready to Use Auth0**. Your social connections on your Auth0 tenant
  should now be configured correctly

### Set up the application

On your Auth0 dashboard, visit **Applications Dropdown** in the left menu.
Select the dropdown and go to **Applications**.

- Select the **Default Application**
- Visit the **Settings** tab
  - Copy the `domain` and `client ID` fields inside **Basic Information**. These
    will be needed shortly.
  - The **Application Properties** should have **Single Page Application** selected
    for **Application Type**,
  - Inside **Application URIs**, please add `http://localhost:3000` to
    **Allowed Callback URLs**, **Allowed Web Origins** and **Allowed Logout URLs**.
- Create the `src/auth_config.json` file from the
  [`src/auth_config.json.example`](https://github.com/auth0-samples/auth0-react-samples/blob/d5848ed710db85d6ef060731b296603c0eca744b/Sample-01/src/auth_config.json.example)
  file as described in the
  [sample app](https://github.com/auth0-samples/auth0-react-samples/tree/d5848ed710db85d6ef060731b296603c0eca744b/Sample-01#create-an-api).
- Once created, paste the `domain` and `client ID` into their respective fields
  inside `src/auth_config.json`. The `audience` key can be removed. The
  login/callback URIs will default to `http://localhost:3000` which is the url
  of our test application.
- [Install](https://github.com/auth0-samples/auth0-react-samples/tree/d5848ed710db85d6ef060731b296603c0eca744b/Sample-01#project-setup)
  the application dependencies and
  [start the dev server](https://github.com/auth0-samples/auth0-react-samples/tree/d5848ed710db85d6ef060731b296603c0eca744b/Sample-01#compile-and-hot-reload-for-development)
- Verify the application is running correctly by visiting
  `http://localhost:3000` and clicking the **Log in** button in the top right
  corner. Select one of our social connections and log in and make sure to
  complete the **Authorize App** prompt. This only needs to be done once. This
  should take you back to the sample app authenticated as the test user. When
  finished, click the **Log Out** dropdown button. Repeat for Google, Microsoft,
  and Facebook or the accounts you would like to test.

Here is what this process should look like for Facebook setup:

<DocsVideo
  src="https://vimeo.com/789093604"
  title="Facebook social application setup"
/>

## Test with Cypress

Now that our application is set up and ready to go, we're ready to write our
automated tests.

:::caution
For these social connections, the
[`experimentalModifyObstructiveThirdPartyCode`](/app/guides/cross-origin-testing#Modifying-Obstructive-Third-Party-Code)
configuration option must be enabled.
:::

## Setting Auth0 app credentials in Cypress

To have access to test user credentials within our tests we need to configure
Cypress to use the social username, password, and name environment variables set
in the `cypress.env.json` file or by one of our
[supported methods](/app/references/environment-variables#Setting).

```json title='cypress.env.json'
{
  "GOOGLE_USERNAME": "",
  "GOOGLE_PASSWORD": "",
  "GOOGLE_NAME": "",
  "MICROSOFT_USERNAME": "",
  "MICROSOFT_PASSWORD": "",
  "MICROSOFT_NAME": "",
  "FACEBOOK_USERNAME": "",
  "FACEBOOK_PASSWORD": "",
  "FACEBOOK_NAME": ""
}
```

### Login with `cy.origin()`

We'll write a custom command called `loginToAuth0ViaSocial` to perform a
login to either Facebook, Google, or Microsoft. This command will use
[`cy.origin()`](/api/commands/origin) to:

1. Navigate to the Auth0 login
2. Select the **Continue with ...** button and sign in with social credentials
3. Sign in and redirect back to the
   [sample app](https://github.com/auth0-samples/auth0-react-samples/tree/d5848ed710db85d6ef060731b296603c0eca744b/Sample-01)
4. Cache the results with [`cy.session()`](/api/commands/session)

For demonstration, we'll have a function for each provider.

#### Facebook Login Function

```js title="cypress/support/commands.ts"
import { domain as Auth0Domain } from '../../src/auth_config.json'

function logIntoFacebook(username: string, password: string, name: string) {
  cy.visit('http://localhost:3000')
  cy.get('#qsLoginBtn').click()

  cy.origin(Auth0Domain, () => {
    cy.scrollTo('bottom')
    cy.get('form[data-provider="facebook"]').submit()
  })

  cy.origin(
    'https://www.facebook.com',
    {
      args: {
        username,
        password,
      },
    },
    ({ username, password }) => {
      cy.get('input#email').type(username)
      cy.get('input#pass').type(password, {
        log: false,
      })
      cy.get('[type="submit"]').contains('Log In').click()
    }
  )

  cy.get('h6.dropdown-header').should('contain', name)
}
```

#### Google Login Function

```js title="cypress/support/commands.ts"
import { domain as Auth0Domain } from '../../src/auth_config.json'

function logIntoGoogle(username: string, password: string, name: string) {
  Cypress.on(
    'uncaught:exception',
    (err) =>
      !err.message.includes('ResizeObserver loop') &&
      !err.message.includes('Error in protected function')
  )
  cy.visit('http://localhost:3000')
  cy.get('#qsLoginBtn').click()

  cy.origin(Auth0Domain, () => {
    cy.scrollTo('bottom')
    cy.get('form[data-provider="google"]').submit()
  })

  cy.origin(
    'https://accounts.google.com',
    {
      args: {
        username,
        password,
      },
    },
    ({ username, password }) => {
      Cypress.on(
        'uncaught:exception',
        (err) =>
          !err.message.includes('ResizeObserver loop') &&
          !err.message.includes('Error in protected function')
      )

      cy.get('input[type="email"]').type(username, {
        log: false,
      })
      // NOTE: The element exists on the original form but is hidden and gets rerendered, which leads to intermittent detached DOM issues
      cy.contains('Next').click().wait(4000)
      cy.get('[type="password"]').type(password, {
        log: false,
      })
      cy.contains('Next').click().wait(4000)
    }
  )

  cy.get('h6.dropdown-header').should('contain', name)
}
```

#### Microsoft Login Function

```js title="cypress/support/commands.ts"
import { domain as Auth0Domain } from '../../src/auth_config.json'

function logIntoMicrosoft(username: string, password: string, name: string) {
  cy.visit('http://localhost:3000')
  cy.get('#qsLoginBtn').click()

  cy.origin(Auth0Domain, () => {
    cy.scrollTo('bottom')
    cy.get('form[data-provider="windowslive"]').submit()
  })

  cy.origin(
    'login.live.com',
    {
      args: {
        username,
        password,
      },
    },
    ({ username, password }) => {
      cy.get('input[type="email"]').type(username)
      cy.get('input[type="submit"]').click()
      cy.get('input[type="password"]').type(password, {
        log: false,
      })
      cy.get('input[type="submit"]').click()
      cy.get('#idBtn_Back').click()
    }
  )

  cy.get('h6.dropdown-header').should('contain', name)
}
```

#### Combined Login Command

We can wire these functions together in a single command, like so:

```ts title="cypress/support/commands.ts"
Cypress.Commands.add(
  'loginToAuth0ViaSocial',
  (SOCIAL_PROVIDER: 'microsoft' | 'google' | 'facebook') => {
    const log = Cypress.log({
      displayName: 'Social LOGIN',
      message: [`🔐 Authenticating | ${SOCIAL_PROVIDER}`],
      // @ts-ignore
      autoEnd: false,
    })
    log.snapshot('before')

    switch (SOCIAL_PROVIDER) {
      case 'microsoft':
        logIntoMicrosoft(
          Cypress.env('MICROSOFT_USERNAME'),
          Cypress.env('MICROSOFT_PASSWORD'),
          Cypress.env('MICROSOFT_NAME')
        )
        break
      case 'google':
        logIntoGoogle(
          Cypress.env('GOOGLE_USERNAME'),
          Cypress.env('GOOGLE_PASSWORD'),
          Cypress.env('GOOGLE_NAME')
        )
        break
      case 'facebook':
        logIntoFacebook(
          Cypress.env('FACEBOOK_USERNAME'),
          Cypress.env('FACEBOOK_PASSWORD'),
          Cypress.env('FACEBOOK_NAME')
        )
        break
      default:
        throw new Error('no social provider configured!')
    }

    log.snapshot('after')
    log.end()
  }
)
```

Now, we can use our `loginToAuth0ViaSocial` command in the test. Below is our
test to login as a user via Auth0 and run a basic check.

```js title='auth.cy.js'
describe('Social Logins Demo', () => {
  beforeEach(() => {
    // can provide facebook, google, or microsoft here
    cy.loginToAuth0ViaSocial('facebook')
    cy.visit('http://localhost:3000/')
  })

  it('navigates to the app after navigation and displays the sample project header', () => {
    cy.get('h1').should('contain', 'React.js Sample Project')
  })
})
```

Here's a sample of what all 3 should look like in order.

<DocsVideo
  src="https://vimeo.com/789093473"
  title="Google, Microsoft, and Facebook social with cy.origin()"
/>

Lastly, we can refactor our login command to take advantage of
[`cy.session()`](/api/commands/session) to store our logged in user so we don't
have to reauthenticate before every test. This also largely cuts down on the
likelihood your account is blocked for frequent authentication attempts. Feel
free to DRY this up a bit!

```ts title="cypress/support/commands.ts"
Cypress.Commands.add(
  'loginToAuth0ViaSocial',
  (SOCIAL_PROVIDER: 'microsoft' | 'google' | 'facebook') => {
    const log = Cypress.log({
      displayName: 'Social LOGIN',
      message: [`🔐 Authenticating | ${SOCIAL_PROVIDER}`],
      // @ts-ignore
      autoEnd: false,
    })
    log.snapshot('before')

    cy.session(
      `social-${SOCIAL_PROVIDER}`,
      () => {
        switch (SOCIAL_PROVIDER) {
          case 'microsoft':
            logIntoMicrosoft(
              Cypress.env('MICROSOFT_USERNAME'),
              Cypress.env('MICROSOFT_PASSWORD'),
              Cypress.env('MICROSOFT_NAME')
            )
            break
          case 'google':
            logIntoGoogle(
              Cypress.env('GOOGLE_USERNAME'),
              Cypress.env('GOOGLE_PASSWORD'),
              Cypress.env('GOOGLE_NAME')
            )
            break
          case 'facebook':
            logIntoFacebook(
              Cypress.env('FACEBOOK_USERNAME'),
              Cypress.env('FACEBOOK_PASSWORD'),
              Cypress.env('FACEBOOK_NAME')
            )
            break
          default:
            throw new Error('no social provider configured!')
        }
      },
      {
        validate: () => {
          cy.visit('http://localhost:3000')
          switch (SOCIAL_PROVIDER) {
            case 'microsoft':
              cy.get('h6.dropdown-header').should(
                'contain',
                Cypress.env('MICROSOFT_NAME')
              )
              break
            case 'google':
              cy.get('h6.dropdown-header').should(
                'contain',
                Cypress.env('GOOGLE_NAME')
              )
              break
            case 'facebook':
              cy.get('h6.dropdown-header').should(
                'contain',
                Cypress.env('FACEBOOK_NAME')
              )
              break
            default:
              throw new Error('no social provider configured!')
          }
        },
      }
    )

    log.snapshot('after')
    log.end()
  }
)
```

<DocsVideo
  src="https://vimeo.com/789093516"
  title="Facebook social with cy.session()"
/>

With the use of [`cy.session()`](/api/commands/session), our tests should now
run quicker!

We hope this guide was able to get you up and running with
[`cy.origin()`](/api/commands/origin) and
[`cy.session()`](/api/commands/session). If you ran into any issues while
following this guide, or have any feedback, please let us know and submit a
[GitHub issue](https://github.com/cypress-io/cypress-documentation/issues/new/choose).
Happy testing!

## See also

- [Cross Origin Testing Guide](/app/guides/cross-origin-testing)
- [AWS Cognito Authentication Guide](/app/guides/authentication-testing/amazon-cognito-authentication)
- [Azure Active Directory Authentication Guide](/app/guides/authentication-testing/azure-active-directory-authentication)
- [`cy.origin()`](/api/commands/origin)
- [`cy.session()`](/api/commands/session)
